#pragma __ENTITIES_INCLUDES__

#ifndef ENTITIES_HPP
#define	ENTITIES_HPP

namespace lms{
    namespace dataaccess{
        template< typename TEntity >
        class GenericRepository;
    }
}

#include <iostream>
#include <cstring>

#include "collections/LinkedList.cpp"

using std::string;

namespace lms {
    namespace entities {

        struct User {
        private:
            string userName;
            string password;
            string fullName;

            friend class dataaccess::GenericRepository< User >;

            struct serializable {
                char userName[30];
                char password[30];
                char fullName[30];
            };

            void parseSerializable(const serializable& serial) {
                
                userName = serial.userName;
                password = serial.password;
                fullName = serial.fullName;
            }
           
        public:
            User();
            User(string userName, string password, string fullName);
            string getUserName();
            string getPassword();
            string getFullName();
            void setUserName(string userName);
            void setPassword(string password);
            void setFullName(string fullName);
            operator serializable();
            bool operator==( const User&  user );
            
        };

        struct Book {
        private:
            string title;
            string author;
            string isbn;
            string editor;
            string category;
            double price;

            friend class dataaccess::GenericRepository< Book >;

            struct serializable {
                char title[30];
                char author[30];
                char isbn[20];
                char editor[30];
                char category[30];
                double price;
            };

            void parseSerializable(const serializable & serial) {
                title = serial.title;
                author = serial.author;
                isbn = serial.isbn;
                editor = serial.editor;
                category = serial.category;
                price = serial.price;
            }


        public:
            Book();
            Book(string title, string author, string isbn, string editor, string category,double price);
            string getTitle();
            string getAuthor();
            string getIsbn();
            string getEditor();
            string getCategory();
            double getPrice();
            
            void setTitle(string title);
            void setAuthor(string author);
            void setIsbn(string isbn);
            void setEditor(string editor);
            void setCategory(string category);
            void setPrice( double price );
            operator serializable();
        };

        struct Customer {
        private:
            string fullName;
            string address;
            string contactNumber;
            string email;

           friend class dataaccess::GenericRepository< Customer >;

            struct serializable {
                char fullName[30];
                char address[30];
                char contactNumber[30];
                char email[30];
            };

            void parseSerializable(const serializable & serial) {
                fullName = serial.fullName;
                address = serial.address;
                contactNumber = serial.contactNumber;
                email = serial.email;
                
            }

        public:
            Customer();
            Customer(string fullName, string address, string contactNumber, string email);
            string getFullName();
            string getAddress();
            string getContactNumber();
            string getEmail();

            void setFullName(string fullName);
            void setAddress(string address);
            void setContactNumber(string contactNumber);
            void setEmail(string email);
            operator serializable();            
        };

        struct OrderDetail
        {
        private:
            int bookAmountPerUnit;
            Book* purchasedBook;
            
        public:
            
            OrderDetail();
            OrderDetail( int amountPerUnit, Book* purchasedBook );
                    
            int getBookAmountPerUnit();
            Book* getPurchasedBook();
            
            void setBookAmountPerUnit( int amountPerUnit );
            void setPurchasedBook( Book* purchasedBook );
        };
        
        struct Order
        {
        private:
            
            static int orderNumber;            
            Customer* customer;
            LinkedList< OrderDetail >* orderDetails;
            
           friend class dataaccess::GenericRepository< Order >;

            struct serializable {
            };

            void parseSerializable(const serializable & serial) {
                
            }
            
        public:
            
            Order();
            Order( Customer* customer,OrderDetail* orderDetail );
            double getTotalCost();
            
            void addOrderDetail( OrderDetail* orderDetail );
            void removeOrderDetail( int index );
            void setOrderDetails(LinkedList<OrderDetail>* orderDetails);            
            void setCustomer(Customer* customer);            
           
            LinkedList<OrderDetail>* getOrderDetails() const;
            Customer* getCustomer() const;            
            operator serializable(); 
        };
    }
}


#endif	/* ENTITIES_HPP */

